#include "DS.h"
#include "Phy_Driver.h"
#include "SM.h"
#include "SMI.h"
#include "AL_Service.h"
#include "CRC.h"

/********************
     暂时排除在工程外 8.3

****************/

BOOL DS_Enable_Flag[PORT_NUM]; //控制变量，控制DS是否使能
BOOL DS_UploadEnable_Flag[PORT_NUM]; //控制变量，控制参数能否上传
BOOL DS_DownLoad_Flag[PORT_NUM]; //控制变量，控制参数能否下载

DS_STATE_TYPE DS_STATE[PORT_NUM];
DS_sub_STATE_TYPE DS_sub_STATE[PORT_NUM];

IndexList_TYPE * IndexList[PORT_NUM];// 指向从Device中读取的IndexList，记得Free内存**********
uint8_t IndexList_Pointer[PORT_NUM];

DS_Object_Entry_TYPE *  DS_Object_Entry[PORT_NUM]; //指向DS_Object在RAM中的读写缓冲区2K***********
uint8_t DS_Data_Object_Len[PORT_NUM]; //DS_Object_Data数据长度

uint32_t Parameter_Checksum[PORT_NUM]; 


DS_Object_Table_TYPE * DS_Table[PORT_NUM]; 

uint32_t DS_DowndLoad_Entry_FlashAddres[PORT_NUM]; //当下载DS_Table时候，Flash中保存Entry的地址

uint16_t Read_DS_Header(uint8_t Port,DS_Object_Header_TYPE * Header ){
     //DS_Object_Data最开始两个字节是 整个表的长度
    Read_Data_From_FlashROM(DS_HEADER_FLASH_ADDRESS(Port),(void *)Header,12);
    return 0x0000;
}


void DS_Init(void){
    //生成CRC表
    make_crc32_table();

    for(uint8_t i=0;i<PORT_NUM;i++){
        if(DS_Enable_Flag[Port]){
            DS_STATE[Port]=DS_WaitingOnDSActivity_1;
        }else{
            DS_STATE[Port]=DS_Off_3;
        }
    }
}



/////////////////////////////////
void Event_DS_Enabled(uint8_t Port){
   if(DS_STATE[Port]==DS_CheckActivationState_0){
       DS_STATE[Port]=DS_WaitingOnDSActivity_1;
       return;
     //  DS_T1(Port);
   }
   if(DS_STATE[Port]==DS_Off_3&&SM_COM_Speed[Port]!=NOT_DETECTED){
     DS_STATE[Port]=DS_UpDownLoad_2;
     // DS_T6(Port);
     return;
   }

   if(DS_STATE[Port]==DS_Off_3&&SM_COM_Speed[Port]==NOT_DETECTED){
       DS_STATE[Port]=DS_WaitingOnDSActivity_1;
       DS_T8(Port);
   }
   
}

void Event_DS_Cleared_or_Disabled(uint8_t Port){
   if(DS_STATE[Port]==DS_CheckActivationState_0){
       DS_STATE[Port]=DS_Off_3;
       //DS_T7(Port);
   }
}

void Event_DS_Delete(uint8_t Port){
    if(DS_STATE[Port]!=DS_CheckActivationState_0||DS_STATE[Port]!=DS_UpDownLoad_2){
         Delete_DS_Data_In_FlashROM();
    }
}

//谁触发Clear？？
void Event_DS_Cleared(uint8_t Port){
    if(DS_STATE[Port]==DS_WaitingOnDSActivity_1){
        DS_STATE[Port]=DS_Off_3;
        Delete_DS_Data_In_FlashROM();
    }
}

void Event_DS_Startup(uint8_t Port){
    if(DS_STATE[Port]==DS_Off_3){
        DS_T14(Port);
        return;
    }
    if(DS_STATE[Port]==DS_WaitingOnDSActivity_1){
        DS_STATE[Port]=DS_UpDownLoad_2;
        DS_sub_STATE[Port]=DS_sub_Checkidentity_4;
        DS_T2(Port);
        return;
                    
    }
}


void Event_DS_UpLoad(uint8_t Port){
    if(DS_STATE[Port]==DS_Off_3){
        DS_T13(Port);
        return;
    }
    if(DS_STATE[Port]==DS_WaitingOnDSActivity_1){
        DS_STATE[Port]=DS_UpDownLoad_2;
        DS_sub_STATE[Port]=DS_sub_Checkidentity_4;
        DS_T4(Port);
        return;
    }
 
}


void Event_DS_Ready(uint8_t Port){
    if(DS_STATE[Port]==DS_UpDownLoad_2){
        DS_STATE[Port]=DS_WaitingOnDSActivity_1;
        DS_T3(Port);
    }
}


void Event_DS_Fault(uint8_t Port){
    if(DS_STATE[Port]==DS_UpDownLoad_2){
        DS_STATE[Port]=DS_WaitingOnDSActivity_1;
        DS_T5(Port);
    }
}

void Event_DS_CheckIdentity_Not_passed_BOOL(uint8_t Port){
   if(DS_sub_STATE[Port]==DS_sub_Checkidentity_4){
       DS_STATE[Port]=DS_sub_Fault_12;
       DS_T15_17(Port);
   }
}

void Event_DS_CheckIdentity_passed_BOOL(uint8_t Port){
    if(DS_sub_STATE[Port]==DS_sub_Checkidentity_4){
        DS_sub_STATE[Port]=DS_sub_CheckMemSize_5;
        DS_T16(Port);
    }
}

void Event_DS_CheckMemSize_passed(uint8_t Port){
    if(DS_sub_STATE[Port]==DS_sub_CheckMemSize_5){
        DS_sub_STATE[Port]=DS_sub_CheckUpload_6;
        DS_T18(Port);
    }
}

void Event_DS_CheckMemSize_Not_passed(uint8_t Port){
     if(DS_sub_STATE[Port]==DS_sub_CheckMemSize_5){
       DS_sub_STATE[Port]=DS_sub_Fault_12;
       DS_T15_17(Port);
   }
}

void Event_DS_Device_Error(uint8_t Port){
   if(DS_sub_STATE[Port]==DS_sub_Upload_Decompose_IL_13){ //此处ReadParameter子状态已经被合并到Decompose状态
       DS_sub_STATE[Port]=DS_sub_Upload_Upload_Fault_16;
       DS_T32_33_34(Port);
   }
}

void Event_DS_COMx_Error(uint8_t Port){ 
   if(DS_sub_STATE[Port]==DS_sub_Upload_Decompose_IL_13){//此处ReadParameter子状态已经被合并到Decompose状态
       DS_sub_STATE[Port]=DS_sub_Upload_Upload_Fault_16;
       DS_T32_33_34(Port);
       return;
   }
   if(DS_sub_STATE[Port]==DS_sub_Dwonload_Write_Parameter_18){
       DS_sub_STATE[Port]=DS_sub_Download_Download_Fault_20;
       DS_T40(Port);
       return;
   }
   if(DS_sub_STATE[Port]==DS_sub_Download_Download_Done_19){
       DS_sub_STATE[Port]=DS_sub_Download_Download_Fault_20;
       DS_T42(Port);
       return;
   }
   
}

void Event_DS_Data_incomplete_For_ReadIndexList(uint8_t Port){
    if(DS_sub_STATE[Port]==DS_sub_Upload_Decompose_IL_13){
        DS_sub_STATE[Port]=DS_sub_Upload_ReadParameter_14;
        DS_T30_ReadIndexList(Port);
    }
}

void Event_DS_Data_incomplete_For_ReadIndexEntry(uint8_t Port){
    if(DS_sub_STATE[Port]==DS_sub_Upload_Decompose_IL_13){
        DS_sub_STATE[Port]=DS_sub_Upload_ReadParameter_14;
        DS_T30_ReadIndexEntry(Port);
    }
}
 
void Event_DS_Data_Read(uint8_t Port){
    if(DS_sub_STATE[Port]==DS_sub_Upload_ReadParameter_14){
        DS_sub_STATE[Port]=DS_sub_Upload_Decompose_IL_13;
        DS_T31(Port); //在T31中判断是否读取IndexList完毕
    }
}

void Event_DS_Data_complete(uint8_t Port){
   if(DS_sub_STATE[Port]==DS_sub_Upload_Decompose_IL_13){
       DS_sub_STATE[Port]=DS_sub_Upload_StoreDataSet_15;
       DS_T35(Port);
   }
}

void Event_DS_Upload_done(uint8_t Port){
    if(DS_sub_STATE[Port]==DS_sub_Upload_StoreDataSet_15){
        DS_sub_STATE[Port]=DS_sub_Ready_11;
        DS_T26(Port);
    }
}


void Event_DS_Valid(uint8_t Port){
    if(DS_sub_STATE[Port]==DS_sub_CheckDSValidity_8){
        DS_sub_STATE[Port]=DS_sub_CheckChecksum_9;
         DS_T22(Port);
    }
}

void Event_DS_Checksum_MisMatch_and_DownloadEnable(uint8_t Port){
    if(DS_sub_STATE[Port]==DS_sub_CheckChecksum_9){
        DS_sub_STATE[Port]=DS_sub_Download_Decompose_Set_17;
        DS_T24(Port);
    }
}

void Event_DS_Checksum_Match_or_DownloadDisable(uint8_t Port){
    if(DS_sub_STATE[Port]==DS_sub_CheckChecksum_9){
        DS_sub_STATE[Port]=DS_sub_Ready_11;
        DS_T25(Port);
    }
}


void Event_DS_Remaining_data(uint8_t Port){
    if(DS_sub_STATE[Port]==DS_sub_Download_Decompose_Set_17){
        DS_sub_STATE[Port]=DS_sub_Dwonload_Write_Parameter_18;
        DS_T37(Port);
    }
}


void Event_DS_Write_done(uint8_t Port){
    if(DS_sub_STATE[Port]==DS_sub_Dwonload_Write_Parameter_18){
        DS_sub_STATE[Port]=DS_sub_Download_Decompose_Set_17;
        DS_T38(Port);//在此函数中判断是否写完毕
    }
}

void Event_DS_Data_completed_Download(uint8_t Port){
    if(DS_sub_STATE[Port]==DS_sub_Download_Decompose_Set_17){
        DS_sub_STATE[Port]=DS_sub_Download_Download_Done_19;
        DS_T41(Port);
    }
}

//*********迁移函数
void DS_T3(uint8_t Port){
    Event_OD_Unblock(Port);
}

void DS_T15_17(uint8_t Port){
    Event_DS_Fault(Port);
}


void DS_T16(uint8_t Port){
    Service_AL_Read_Req(Port,0x0003,0x03,CallBack_Read_DS_Size);
}

void DS_T18(uint8_t Port){
    Service_AL_Read_Req(Port,0x0003,0x02,Callback_Read_State_Property);
}

void DS_T19(uint8_t Port){
    uint8_t DS_Cmd=0x01;
    //Service_AL_Write_Req(Port,0x0003,0x01,&DS_Cmd,)
    Service_AL_Write_Req(Port,0x0003,0x01,&DS_Cmd,1,CallBack_DS_Cmd_DS_UplaodStart);
}

void DS_T20_43(uint8_t Port){
    //验证DS有效性，默认总是有效
    Event_DS_Valid(Port);
}

void DS_T22(uint8_t Port){
    Action_DS_Checksum(Port); //进行CRC校验
}

void DS_T24(uint8_t Port){
    DS_DowndLoad_Entry_FlashAddres[Port]=DS_ENTRYS_FLASH_ADDRESS[Port];

    uint8_t DS_DownloadStart=0x03;
   Service_AL_Write_Req(Port,0x0003,0x01,&DS_DownloadStart,1,Call_Back_DS_Write_DownLoadStart);　
  
}

void DS_T25(uint8_t Port){

}

void DS_T26(uint8_t Port){
    //已经发送过CM DS_Ready,此处仅仅调转
    DS_sub_STATE[Port]=DS_sub_None;
    DS_STATE[Port]=DS_WaitingOnDSActivity_1;
    DS_T3(Port);


}

void DS_T30_ReadIndexList(uint8_t Port){
   //预先为读取到的DS_Object预留最大的空间
   DS_Object_Entry[Port]=(DS_Object_Entry_TYPE *)malloc(sizeof(DS_Object_Entry_TYPE)+232); 
  

 //初始化DS_Data_Object_Len长度

   DS_Data_Object_Len[Port]=0;//DS_Data至少占4个字节 Table G1

  
   Service_AL_Read_Req(Port,0x0003,0x05,CallBack_Read_DS_IndexList);
}

void DS_T30_ReadIndexEntry(uint8_t Port){
    
    
   uint16_t index=IndexList[Port][IndexList_Pointer[Port]].Entry_Index;
   uint8_t  subindex=IndexList[Port][IndexList_Pointer[Port]].Entry_Subindex;
   IndexList_Pointer[Port]+=1;//更新IndexList指针
  DS_Object_Entry[Port]->ISDU_Index=index;
   DS_Object_Entry[Port]->ISDU_Subindex=subindex;

   Service_AL_Read_Req(Port,index,subindex,CallBack_Read_DS_IndexEntry);
}

void DS_T31(uint8_t Port){
    //判断Data是否读取完毕
     if(IndexList[Port][IndexList_Pointer[Port]].Entry_Index==0){

        Event_DS_Data_complete(Port);
     }else{
        Event_DS_Data_incomplete_For_ReadIndexEntry(Port);
     }
}  

void DS_T32_33_34(uint8_t Port){
    free(IndexList[Port]);
}

void DS_T35(uint8_t Port){
    //读取完DS_Table，需要做些处理
    free(IndexList[Port]); //清空malloc分配的IndexList内存
    Service_AL_Read_Req(Port,0x0003,0x04,CallBack_Read_Parameter_Checksum);
}        

void DS_T37(uint8_t Port){
    uint16_t ISDU_Index;
    uint8_t  ISDU_subIndex;
    uint8_t ISDU_LEN;
    uint8_t * ISDU_Data;
    
    //读取一条Entry数据
    Read_Data_From_FlashROM(DS_DowndLoad_Entry_FlashAddres[Port],&ISDU_Index,2);     
    Read_Data_From_FlashROM(DS_DowndLoad_Entry_FlashAddres[Port]+2,&ISDU_subIndex,1);
    Read_Data_From_FlashROM(DS_DowndLoad_Entry_FlashAddres[Port]+3,&ISDU_LEN,1);
    ISDU_Data=malloc(ISDU_LEN); //申请空间
    Read_Data_From_FlashROM(DS_DowndLoad_Entry_FlashAddres[Port]+4,ISDU_Data,ISDU_LEN);
    //更新下一条Entry的Flash地址
    DS_DowndLoad_Entry_FlashAddres[Port]+=(ISDU_LEN+4);

    Service_AL_Write_Req(Port,ISDU_Index,ISDU_subIndex,ISDU_Data,ISDU_LEN,CallBack_Write_DS_one_Entry);
    free(ISDU_Data); //释放空间
   
}


void DS_T38(uint8_t Port){
    DS_DowndLoad_Entry_FlashAddres;
    uint16_t DS_Table_Len; 
    //读取DS中保存的每个端口保存的数据长度
    Read_Data_From_FlashROM(DS_TOTAL_LENGTH_FLASH_ADDRESS(Port),&DS_Table_Len,2);
    //计算在Flash中的每个端口保存数据的末尾地址
    uint32_t End_Of_Entry_In_Flashrom= DS_FLASH_ROM_ADDRESS(Port)+DS_Table_Len;  

    if(DS_DowndLoad_Entry_FlashAddres>=End_Of_Entry_In_Flashrom){ //已经下载结束
        
        Event_DS_Data_completed_Download(Port);
    }else{ //没有下载结束

    }
}


void DS_T41(uint8_t Port){
    uint8_t DS_DownLoad_End=0x04;
 
    Service_AL_Write_Req(Port,0x0003,0x01,&DS_DownLoad_End,1,Callback_Write_DownLoadEnd);
     
}

//DS_T16回调函数
void CallBack_Read_DS_Size(uint8_t Port, uint8_t * Data, uint8_t DataLen, uint16_t ErrorInfo){
    //因为是预留了足够的空间，所以总是Pass
    Event_DS_CheckMemSize_passed(Port);
}

//DS_T18回调函数
void Callback_Read_State_Property(uint8_t Port, uint8_t * Data, uint8_t DataLen, uint16_t ErrorInfo){
    uint8_t DataFromDevice=*Data&0x80;
    BOOL DS_UPLOAD_FLAG_From_Device;
    if(DataFromDevice==0x80){ //DS_UPLOAD_REQ
          DS_UPLOAD_FLAG_From_Device=True;
    }else{         //Not DS_UPLOAD_REQ
          DS_UPLOAD_FLAG_From_Device=False;
    }
    if(!DS_Enable_Flag){
       DS_sub_STATE[Port]=DS_sub_Fault_12;
       DS_T29(Port);
       return;
    }
    else if(DS_UPLOAD_FLAG_From_Device&&DS_UploadEnable_Flag){ 
        //进入Upload_7子状态
        DS_sub_STATE[Port]=DS_sub_Upload_Decompose_IL_13; //子状态直接转移
        DS_T19(Port);
        return;
    }
    else if(DS_UPLOAD_FLAG_From_Device&&!DS_UploadEnable_Flag){
        DS_sub_STATE[Port]=DS_sub_CheckDSValidity_8;
        DS_T20_43(Port);
        return;
    }else if(!DS_UPLOAD_FLAG_From_Device){
        DS_sub_STATE[Port]=DS_sub_CheckDSValidity_8;
        DS_T20_43(Port);
        return;
    }
}

void CallBack_DS_Cmd_DS_UplaodStart(uint8_t Port, uint16_t ErrorInfo){
    if(ErrorInfo==0){  //正确写入DS命令
     Event_DS_Data_incomplete_For_ReadIndexList(Port);
   
    }else{
        //写入DS命令错误
        DS_sub_STATE[Port]=DS_sub_Upload_Upload_Fault_16;
        DS_T32_33_34(Port);
    }
}


void  CallBack_Read_DS_IndexList(uint8_t Port, uint8_t * Data, uint8_t DataLen, uint16_t ErrorInfo){
     if(ErrorInfo==0){
          IndexList[Port]=(IndexList_TYPE *)malloc(DataLen);
          memcpy(IndexList[Port],Data,DataLen); //保存IndexList
          IndexList_Pointer[Port]=0;

        
          Event_DS_Data_Read(Port);
             
         
     }else{
         if(ErrorInfo&0xFF00==0x8000){ //ErrorCode==0x80
            Event_DS_Device_Error(Port);
         }else{
            Event_DS_COMx_Error(Port);
         }
     }
}
 

void CallBack_Read_DS_IndexEntry(uint8_t Port, uint8_t * Data, uint8_t DataLen, uint16_t ErrorInfo){
    

    DS_Object_Entry[Port]->ISDU_Length=DataLen;
    memcpy(DS_Object_Entry[Port]->ISDU_Data,Data,DataLen);
    //每读取一次Entry，就保存到Flash

    Save_Data_To_FlashROM(DS_ENTRYS_FLASH_ADDRESS(Port)+DS_Data_Object_Len[Port],(void *)DS_Object_Entry[Port],DataLen+4);
    //更新DS_ObjecT_Table长度

    free(DS_Object_Entry[Port]); //清空堆内存
    DS_Data_Object_Len[Port]+=(DataLen+4); //更新DS数据长度

    Event_DS_Data_Read(Port);

}

void CallBack_Read_Parameter_Checksum(uint8_t Port, uint8_t * Data, uint8_t DataLen, uint16_t ErrorInfo){
   // memcpy((void *)&Parameter_Checksum[Port],Data,DataLen);
   if(ErrorInfo!=0){
       Event_DS_COMx_Error(Port);
       return;
   }
    DS_Object_Header_TYPE DS_Header;
    DS_Header.DeviceID=DeviceID;
    DS_Header.FunctionID=FunctionID;
    DS_Header.VendorID=VendorID;
    memcpy(DS_Header.Parameter_Checksum,Data,4);
    
    //保存DS_Table数据总长度到Flash
    Save_Data_To_FlashROM(DS_TOTAL_LENGTH_FLASH_ADDRESS(Port),&DS_Data_Object_Len[Port],2);
    //保存DS_Header到Flash
    Save_Data_To_FlashROM(DS_HEADER_FLASH_ADDRESS(Port),&DS_Header,sizeof(DS_Object_Header_TYPE));
    //DS_Object前面已经保存过

    //向Device发送DS_UploadEnd
    uint8_t DS_UploadEnd=0x02;
    Service_AL_Write_Req(Port,0x0003,0x01,&DS_UploadEnd,1,CallBack_Write_DS_UploadEnd);

    Event_DS_Upload_done(Port);
}


void CallBack_Write_DS_UploadEnd(uint8_t Port, uint16_t ErrorInfo){
    //通知CM DS_Ready
    Event_DS_Ready(Port);
}


void Call_Back_DS_Write_DownLoadStart(uint8_t Port,uint16_t ErrorInfo){
       if(ErrorInfo==0){
           Event_DS_Remaining_data(Port); 
       }else{

           DS_sub_STATE[Port]=DS_sub_Dwonload_Write_Parameter_18;
           Event_DS_COMx_Error(Port);
       }
       
}


void  CallBack_Write_DS_one_Entry(uint8_t Port, uint16_t ErrorInfo){
     if(ErrorInfo==0){
         Event_DS_Write_done(Port);
     }else{
         Event_DS_COMx_Error(Port);
     }
}
  

void Callback_Write_DownLoadEnd(uint8_t Port,uint16_t ErrorInfo){
    if(ErrorInfo==0){

    }else{
        Event_DS_COMx_Error(Port);
    }
}
//////////////////////////////////////

void Action_DS_CheckIdentity_4(uint8_t Port){
    DS_Object_Header_TYPE Header;
    Read_DS_Header(Port,&Header);
    if((Header.DeviceID==0&&Header.VendorID==0)||(Header.DeviceID==SMI_PortConfigList[Port].DeviceID&&Header.VendorID==SMI_PortConfigList[Port].VendorID)){
  
       Event_DS_CheckIdentity_passed_BOOL(Port);
    }else{
        Event_DS_CheckIdentity_Not_passed_BOOL(Port);
    }

}

void Action_DS_Checksum(uint8_t Port){
    uint32_t calcuCrc=0xFFFFFFFF; //初始化CRC
    //读取保存在Flash中的DS数据长度,不包括长度本身
    uint16_t DS_Table_Len;
    Read_Data_From_FlashROM(DS_TOTAL_LENGTH_FLASH_ADDRESS(Port),&DS_Table_Len,2);
    DS_Table_Len-=2; //减去长度本身占用字节
    //读取保存在Flash中的Checksum
    uint32_t Checksum;
    Read_Data_From_FlashROM(DS_CHECKSUM_FLASH_ADDRESS(Port),&Checksum,4);
    //提取DS_Table本身
    uint8_t *DS_Table=malloc(DS_Table_Len);
    Read_Data_From_FlashROM(DS_HEADER_FLASH_ADDRESS(Port),DS_Table,DS_Table_Len);
    //计算CRC
    calcuCrc=make_crc(calcuCrc,DS_Table,DS_Table_Len); 
    //比较校验结果
    BOOL Checksum_Match;
    if(calcuCrc==Checksum){
        Checksum_Match=True;
    }else{
        Checksum_Match=False;
    }

    if(!Checksum_Match&&DS_DownLoad_Flag){
        Event_DS_Checksum_MisMatch_and_DownloadEnable(Port);
    }else{
        Event_DS_Checksum_Match_or_DownloadDisable(Port);
    }

    
    

    
}